package com.daqi.bleaction.service

import android.app.Service
import android.bluetooth.BluetoothAdapter
import android.bluetooth.BluetoothManager
import android.bluetooth.le.AdvertiseCallback
import android.bluetooth.le.AdvertiseData
import android.bluetooth.le.AdvertiseSettings
import android.bluetooth.le.BluetoothLeAdvertiser
import android.content.Context
import android.content.Intent
import android.os.Binder
import android.os.IBinder
import android.os.ParcelUuid
import android.util.Log
import com.daqi.bleaction.BleScanHelper
import com.daqi.bleaction.BluetoothUtils.hexStringToBytes
import com.daqi.bleaction.UUID_SERVICE
import com.daqi.bleaction.UUID_SERVICE2
import com.daqi.bleaction.bean.BleDevice
import java.util.*

public class MyBleService : Service() {
    //蓝牙扫描辅助类
    private lateinit var mBleScanHelper: BleScanHelper

    //扫描响应数据(可选，当客户端扫描时才发送)
    private lateinit var mScanResponseData: AdvertiseData

    //广播时间(设置为0则持续广播)
    private val mTime = 6000;
    private lateinit var mAdvertiseCallback: daqiAdvertiseCallback

    //广播设置(必须)
    private lateinit var mAdvertiseSettings: AdvertiseSettings
    private lateinit var callBack: CallBack;

    //蓝牙设配器
    private lateinit var mBluetoothAdapter: BluetoothAdapter

    //广播数据(必须，广播启动就会发送)
    //BLE广播操作类
    private var mBluetoothLeAdvertiser: BluetoothLeAdvertiser? = null
    private lateinit var mAdvertiseData: AdvertiseData

    //    override fun onBind(intent: Intent): IBinder {
//    }
    //client 可以通过Binder获取Service实例
    inner class MyBinder : Binder() {
        val service: MyBleService
            get() = this@MyBleService
    }

    //通过binder实现调用者client与Service之间的通信
    private val binder = MyBinder()

    interface CallBack {
        fun dataChaged(bleDevice: BleDevice);
        fun finished();
    }

    fun setCallBack(callBack: CallBack) {
        this.callBack = callBack;
    }

    private fun startAdvertising() {
        //初始化广播设置
        //判断蓝牙是否开启，如果关闭则请求打开蓝牙
//        if (!mBluetoothAdapter.isEnabled()) {
//            val intent = Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE)
//            startActivityForResult(intent, OpenBluetooth_Request_Code)
//            return
//        }
        val manager = this.getSystemService(Context.BLUETOOTH_SERVICE) as BluetoothManager
        if (manager == null) {
            return
        }
        mBluetoothAdapter = manager.adapter
        //设置蓝牙广播名称
        mBluetoothAdapter.name = "daqi"

        //初始化广播设置
        mAdvertiseSettings = AdvertiseSettings.Builder()
            //设置广播模式，以控制广播的功率和延迟。 ADVERTISE_MODE_LOW_LATENCY为高功率，低延迟
            .setAdvertiseMode(AdvertiseSettings.ADVERTISE_MODE_LOW_LATENCY)
            //设置蓝牙广播发射功率级别
            .setTxPowerLevel(AdvertiseSettings.ADVERTISE_TX_POWER_HIGH)
            //广播时限。最多180000毫秒。值为0将禁用时间限制。（不设置则为无限广播时长）
            .setTimeout(mTime)
            //设置广告类型是可连接还是不可连接。
            .setConnectable(true)
            .build()
        val randoms = (0..10).random()
        var sm: Array<String> = arrayOf("1", "2", "3", "4", "6", "2", "9")
        var str = sm.toString();
        //设置广播报文
        val byte = ByteArray(7) { sm[it].trim().toByte() }
        mAdvertiseData = AdvertiseData.Builder()
            //设置广播包中是否包含设备名称。
            .setIncludeDeviceName(true)
            //设置广播包中是否包含发射功率
            .setIncludeTxPowerLevel(true)
            //设置UUID
//            .addServiceUuid(ParcelUuid(UUID_SERVICE))
//            .addServiceUuid(ParcelUuid(UUID_SERVICE2))
            .addManufacturerData(0x06, "test brodcase".toByteArray())
            .build()

        //设置广播扫描响应报文(可选)
        mScanResponseData = AdvertiseData.Builder()
            //自定义服务数据，将其转化为字节数组传入
//            .addServiceData(ParcelUuid(UUID_SERVICE2), byteArrayOf(2, 3, 4))
            //设备厂商自定义数据，将其转化为字节数组传入
            .addManufacturerData( 0x06, "test receive".toByteArray())
//            .addManufacturerData(0x06, byteArrayOf(1, 2, 3))
            .build()
        mAdvertiseCallback = daqiAdvertiseCallback()
        //获取BLE广播操作对象
        //官网建议获取mBluetoothLeAdvertiser时，先做mBluetoothAdapter.isMultipleAdvertisementSupported判断，
        // 但部分华为手机支持Ble广播却还是返回false,所以最后以mBluetoothLeAdvertiser是否不为空且蓝牙打开为准
        mBluetoothLeAdvertiser = mBluetoothAdapter.bluetoothLeAdvertiser
        //蓝牙关闭或者不支持
        if (mBluetoothLeAdvertiser != null && mBluetoothAdapter.isEnabled()) {
            Log.d(
                "daqia", "mBluetoothLeAdvertiser != null = ${mBluetoothLeAdvertiser != null} " +
                        "mBluetoothAdapter.isMultipleAdvertisementSupported = ${mBluetoothAdapter.isMultipleAdvertisementSupported}"
            )
            //开始广播（不附带扫描响应报文）
            //mBluetoothLeAdvertiser.startAdvertising(mAdvertiseSettings, mAdvertiseData, mAdvertiseCallback)
            //开始广播（附带扫描响应报文）
            mBluetoothLeAdvertiser?.startAdvertising(
                mAdvertiseSettings, mAdvertiseData,
                mScanResponseData, mAdvertiseCallback
            )
        } else {
            //前面已经确保在蓝牙开启时才广播，排除蓝牙未开启
//            displayInfo("该手机芯片不支持BLE广播")
        }
    }

    override fun onCreate() {
        mBleScanHelper = BleScanHelper(this);
        mBleScanHelper.setOnScanListener(object:BleScanHelper.onScanListener{
            override fun onNext(device: BleDevice) {
                callBack.dataChaged(device)
            }

            override fun onFinish() {
                callBack.finished();
            }

        } )
        startAdvertising();
    }

    override fun onBind(p0: Intent?): IBinder? {
        return binder;
    }


    /**
     * 蓝牙广播回调类
     */
    public inner class daqiAdvertiseCallback : AdvertiseCallback() {
        override fun onStartSuccess(settingsInEffect: AdvertiseSettings) {
            //如果持续广播 则不提醒关闭
            if (mTime != 0) {
                //设置关闭提醒
                Timer().schedule(object : TimerTask() {
                    override fun run() {
                        mBleScanHelper.startScanBle(6000)
                    }
                }, 6000)
            }
            val advertiseInfo = StringBuffer("启动Ble广播成功")
            //连接性
            if (settingsInEffect.isConnectable) {
                advertiseInfo.append(", 可连接")
            } else {
                advertiseInfo.append(", 不可连接")
            }
            //广播时长
            if (settingsInEffect.timeout == 0) {
                advertiseInfo.append(", 持续广播")
            } else {
                advertiseInfo.append(", 广播时长 ${settingsInEffect.timeout} ms")
            }
//            displayInfo(advertiseInfo.toString())
        }

        //具体失败返回码可以到官网查看
        override fun onStartFailure(errorCode: Int) {
            if (errorCode == ADVERTISE_FAILED_DATA_TOO_LARGE) {
//                displayInfo("启动Ble广播失败 数据报文超出31字节")
            } else {
//                displayInfo("启动Ble广播失败 errorCode = $errorCode")
            }
        }
    }

}